/**
 *
 * 核心工具类。
 *
 * Created by ChenYong on 2017-02-24.
 *
 */



//--------------------[常量定义]--------------------/
/** 用户名的正则表达式 */
var usernameRE = /^[0-9A-Za-z_]{5,20}$/i;
/** 邮箱的正则表达式 */
var mailRE = /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/i;
/** 手机号的正则表达式 */
var phoneRE = /^1[3-9][0-9]{9}$/i;
/** 密码的正则表达式 */
var passwdRE = /^[0-9a-zA-Z]{6,20}$/i;
/** 验证码的正则表达式 */
var captchaRE = /^[0-9A-Za-z]{6}$/i;
/** 完整 URL 的正则表达式 */
var urlFullRE = /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i;
/** 部分 URL 的正则表达式 */
var urlOnlyRE = /^#\/[A-Za-z_.\d-]+(\/[A-Za-z_.\d-]+)*$/i;
/** 中文的正则表达式 */
var chineseRE = /^[\u4e00-\u9fa50-9a-zA-Z_]+$/i;
/** 编码的正则表达式 */
var codeRE = /^[A-Z]+[0-9A-Z]*$/i;
/** Font Awesome 字体正则表达式 */
var fontAwesomeRE = /^fa fa-[0-9a-z]+(-[0-9a-z]+)*$/i;
/** 数字的正则表达式 */
var numberRE = /^[0-9]+$/i;
/** 字典代码的正则表达式 */
var dictCodeRE = /^D[0-9]{1,10}$/i;
/** 价格的正则表达式 */
var priceRE = /^[0-9]{1,8}(\.[0-9][0-9]?)?$/i;
//--------------------[/常量定义]--------------------/


//--------------------[添加原型方法]--------------------//
/**
 *
 * 替换所有旧字符串。
 *
 * @param oldStr 旧字符串
 * @param newStr 新字符串
 * @returns 替换后的字符串
 *
 */
String.prototype.replaceAll = function (oldStr, newStr) {
    return this.replace(new RegExp(oldStr, "gm"), newStr);
};

/**
 *
 * 格式化字符串。<br>
 * 两种调用方式：<br>
 * var s1 = "我是{0}，今年{1}了";<br>
 * var s2 = "我是{name}，今年{age}了";<br>
 * var result1 = s1.format("loogn", 22);<br>
 * var result2 = s2.format({name : "loogn", age : 22});<br>
 * 结果：“我是loogn，今年22了”。<br>
 *
 * @param param 参数
 * @returns {String} 格式化后的字符串
 *
 */
String.prototype.format = function (param) {
    if (arguments.length > 0) {
        var result = this;

        if ((arguments.length === 1) && ($.type(param) === "object")) {
            for (var key in param) {
                var reg = new RegExp("({" + key + "})", "g");

                result = result.replace(reg, param[key]);
            }
        } else {
            for (var i = 0; i < arguments.length; i++) {
                if ($.type(arguments[i]) === "undefined") {
                    return "";
                } else {
                    var reg = new RegExp("({[" + i + "]})", "g");

                    result = result.replace(reg, arguments[i]);
                }
            }
        }

        return result;
    } else {
        return this;
    }
};
//--------------------[/添加原型方法]--------------------//


/**!
 *
 * jQuery 工具插件。
 *
 */
(function ($) {
    /**
     *
     * 对象为空。
     *
     * @param o 对象
     * @returns {Boolean} 是否为空：
     * <ol>
     *    <li>true-为空；</li>
     *    <li>false-不为空。</li>
     * </ol>
     *
     */
    $.isNull = function (o) {
        try {
            if (($.type(o) === "undefined") || (o == null)) {
                return true;
            }

            return false;
        } catch (e) {
            return true;
        }
    };

    /**
     *
     * 对象不为空。
     *
     * @param o 对象
     * @returns {Boolean} 是否为空：
     * <ol>
     *    <li>true-不为空；</li>
     *    <li>false-为空。</li>
     * </ol>
     *
     */
    $.isNotNull = function (o) {
        return !$.isNull(o);
    };

    /**
     *
     * 字符串为空。
     *
     * @param str 字符串
     * @returns {Boolean} 是否为空：
     * <ol>
     *    <li>true-为空；</li>
     *    <li>false-不为空。</li>
     * </ol>
     *
     */
    $.isBlank = function (str) {
        try {
            if (($.type(str) === "undefined") || (str == null)) {
                return true;
            } else if (($.type(str) === "number") || ($.type(str) === "boolean")) {
                return false;
            } else if ($.type(str) === "string") {
                if ($.trim(str).length === 0) {
                    return true;
                } else {
                    return false;
                }
            }

            return true;
        } catch (e) {
            return true;
        }
    };

    /**
     *
     * 字符串不为空。
     *
     * @param str 字符串
     * @returns {Boolean} 是否为空：
     * <ol>
     *    <li>true-不为空；</li>
     *    <li>false-为空。</li>
     * </ol>
     *
     */
    $.isNotBlank = function (str) {
        return !$.isBlank(str);
    };

    /**
     *
     * 判断变量 v 是否存在。
     *
     * @param v 变量
     * @returns {Boolean} 是否存在：
     * <ol>
     *    <li>true-存在；</li>
     *    <li>false-不存在。</li>
     * </ol>
     *
     */
    $.isVarExists = function (v) {
        try {
            if ($.type(v) === "undefined") {
                return false;
            }

            return true;
        } catch (e) {
            return false;
        }
    };

    /**
     *
     * 判断非空变量是否为原生对象。
     *
     * @param o 变量
     * @returns {Boolean} 是否为原生对象：
     * <ol>
     *    <li>true-是；</li>
     *    <li>false-否。</li>
     * </ol>
     *
     */
    $.isObject = function (o) {
        try {
            return $.isPlainObject(o);
        } catch (e) {
            return false;
        }
    };

    /**
     *
     * 判断非空变量是否为 jQuery 对象。
     *
     * @param o 变量
     * @returns {Boolean} 是否为 jQuery 对象：
     * <ol>
     *    <li>true-是；</li>
     *    <li>false-否。</li>
     * </ol>
     *
     */
    $.is_jQueryObj = function (o) {
        try {
            return $.isNotNull(o) && $.isNotBlank(o.jquery) && (o.length > 0);
        } catch (e) {
            return false;
        }
    };

    /**
     *
     * 判断变量是否为数字。
     *
     * @param o 变量
     * @returns {Boolean} 是否为数字：
     * <ol>
     *    <li>true-是；</li>
     *    <li>false-否。</li>
     * </ol>
     *
     */
    $.isNumber = function (o) {
        try {
            return $.isNumeric(o);
        } catch (e) {
            return false;
        }
    };

    /**
     *
     * 判断变量是否为布尔值。
     *
     * @param o 变量
     * @returns {Boolean} 是否为布尔值：
     * <ol>
     *    <li>true-是；</li>
     *    <li>false-否。</li>
     * </ol>
     *
     */
    $.isBoolean = function (o) {
        try {
            if ($.type(o) === "boolean") {
                return true;
            }

            return false;
        } catch (e) {
            return false;
        }
    };
})(jQuery);


/**
 *
 * 核心。
 *
 */
(function (window) {
    // 核心对象
    var boil = {};
    // 总共发送的 ajax 个数
    var ajaxCount = 0;
    // 需要显示等待框的 ajax 个数
    var ajaxLodingCount = 0;

    /**
     *
     * 显示等待框。
     *
     * @param msg 消息
     *
     */
    boil.showProgress = function (msg) {
        if ($.isBlank(msg)) {
            api.showProgress({
                style: "default",
                animationType: "fade",
                title: "",
                text: "",
                modal: false
            });
        } else {
            api.showProgress({
                style: "default",
                animationType: "fade",
                title: "",
                text: msg,
                modal: false
            });
        }
    };

    /**
     *
     * 隐藏等待框。
     *
     */
    boil.hideProgress = function () {
        api.hideProgress();
    };

    /**
     *
     * 提示信息。
     *
     * @param msg 消息
     *
     */
    boil.toast = function (msg) {
        if ($.isNotBlank(msg)) {
            api.toast({
                msg: msg,
                duration: 3000,
                location: "bottom"
            });
        }
    };

    /**
     *
     * 弹出提示框。
     *
     * @param msg 消息
     *
     */
    boil.alert = function (msg) {
        if ($.isNotBlank(msg)) {
            api.alert({
                title: "提示",
                msg: msg,
                buttons: ["确定"]
            }, function (ret, err) {
            });
        }
    };

    /**
     *
     * 根据 key 设置偏好中的值。
     *
     * @param key 键
     * @param value 值
     *
     */
    boil.setPrefs = function (key, value) {
        if ($.isNotBlank(key)) {
            api.setPrefs({
                key: key,
                value: value
            });
        }
    };

    /**
     *
     * 根据 key 获取偏好中的值。
     *
     * @param key 键
     *
     */
    boil.getPrefs = function (key) {
        if ($.isNotBlank(key)) {
            return api.getPrefs({
                sync: true,
                key: key
            });
        }
    };

    /**
     *
     * 根据 key 删除偏好中的值。
     *
     * @param key 键
     *
     */
    boil.removePrefs = function (key) {
        if ($.isNotBlank(key)) {
            api.removePrefs({
                key: key
            });
        }
    };

    /**
     *
     * 设置偏好中的服务器 IP。
     *
     * @param ip 服务器 IP
     *
     */
    boil.setServerIp = function (serverIp) {
        boil.setPrefs("SERVER_IP", ($.isBlank(serverIp) ? "" : serverIp));
    };

    /**
     *
     * 获取偏好中的服务器 IP。
     *
     * @return {string} 服务器 IP
     *
     */
    boil.getServerIp = function () {
        return ($.isBlank(boil.getPrefs("SERVER_IP")) ? "" : boil.getPrefs("SERVER_IP"));
    };

    /**
     *
     * 获取六盘水的服务器 IP。
     *
     * @return {string} 服务器 IP
     *
     */
    boil.getLpsServerIp = function () {
        return "http://111.121.223.244:8081/";
    };

    /**
     *
     * 获取大屏的 IP。
     *
     * @return {string} 大屏的 IP。
     *
     */
    boil.getBigScreenIp = function () {
        return "http://111.121.223.244:8088/";
    };

    /**
     *
     * 设置偏好中的账号。
     *
     * @param username 账号
     *
     */
    boil.setUsername = function (username) {
        boil.setPrefs("USERNAME", ($.isBlank(username) ? "" : username));
    };

    /**
     *
     * 获取偏好中的账号。
     *
     * @return {string} 偏好中的账号
     *
     */
    boil.getUsername = function () {
        return ($.isBlank(boil.getPrefs("USERNAME")) ? "" : boil.getPrefs("USERNAME"));
    };

    /**
     *
     * 设置偏好中的密码。
     *
     * @param passwd 密码
     *
     */
    boil.setPasswd = function (passwd) {
        boil.setPrefs("PASSWD", ($.isBlank(passwd) ? "" : passwd));
    };

    /**
     *
     * 获取偏好中的密码。
     *
     * @return {string} 偏好中的密码
     *
     */
    boil.getPasswd = function () {
        return ($.isBlank(boil.getPrefs("PASSWD")) ? "" : boil.getPrefs("PASSWD"));
    };

    /**
     *
     * 设置偏好中的登录标志。
     *
     * @param loginFlag 登录标志
     * <ul>
     *     <li>1-已登录</li>
     *     <li>-1或其他数字-未登录</li>
     * </ul>
     *
     */
    boil.setLoginFlag = function (loginFlag) {
        boil.setPrefs("LOGIN_FLAG", ($.isBlank(loginFlag) ? "-1" : loginFlag));
    };

    /**
     *
     * 获取偏好中的登录标志。
     *
     * @return {string}
     * <br>
     * <ul>
     *     <li>1-已登录</li>
     *     <li>-1或其他数字-未登录</li>
     * </ul>
     *
     */
    boil.getLoginFlag = function () {
        return ($.isBlank(boil.getPrefs("LOGIN_FLAG")) ? "-1" : boil.getPrefs("LOGIN_FLAG"));
    };

    /**
     *
     * 判断是否已登录。
     *
     * @return {boolean}
     * <ol>
     *     <li>true-已登录；</li>
     *     <li>false-未登录。</li>
     * </ol>
     *
     */
    boil.isLogin = function () {
        if (boil.getLoginFlag() == "1") {
            return true;
        }

        return false;
    };

    /**
     *
     * 设置偏好中的登录人员的区县编码。
     *
     * @param loginCountyNo 登录人员的区县编码
     *
     *
     */
    boil.setLoginCountyNo = function (loginCountyNo) {
        boil.setPrefs("LOGIN_COUNTY_NO", ($.isBlank(loginCountyNo) ? "" : loginCountyNo));
    };

    /**
     *
     * 获取偏好中的登录人员的区县编码。
     *
     * @return {string} 偏好中的登录人员的区县编码
     *
     */
    boil.getLoginCountyNo = function () {
        return ($.isBlank(boil.getPrefs("LOGIN_COUNTY_NO")) ? "" : boil.getPrefs("LOGIN_COUNTY_NO"));
    };

    /**
     *
     * 设置偏好中的当前煤矿编码。
     *
     * @param orgNo 当前煤矿编码
     *
     */
    boil.setCurrentDistrictCountyNo = function (currentDistrictCountyNo) {
        boil.setPrefs("CURRENT_DISTRICT_COUNTY_NO", ($.isBlank(currentDistrictCountyNo) ? "" : currentDistrictCountyNo));
    };

    /**
     *
     * 获取偏好中的当前煤矿编码。
     *
     * @return {string} 偏好中的当前煤矿编码
     *
     */
    boil.getCurrentDistrictCountyNo = function () {
        return ($.isBlank(boil.getPrefs("CURRENT_DISTRICT_COUNTY_NO")) ? "" : boil.getPrefs("CURRENT_DISTRICT_COUNTY_NO"));
    };

    /**
     *
     * 设置偏好中的登录人员的区县名称。
     *
     * @param loginCountyName 登录人员的区县名称
     *
     */
    boil.setLoginCountyName = function (loginCountyName) {
        boil.setPrefs("LOGIN_COUNTY_NAME", ($.isBlank(loginCountyName) ? "" : loginCountyName));
    };

    /**
     *
     * 获取偏好中的登录人员的区县名称。
     *
     * @return {string} 偏好中的登录人员的区县名称
     *
     */
    boil.getLoginCountyName = function () {
        return ($.isBlank(boil.getPrefs("LOGIN_COUNTY_NAME")) ? "" : boil.getPrefs("LOGIN_COUNTY_NAME"));
    };

    /**
     *
     * 设置偏好中的煤矿所属的区县编码。
     *
     * @param countyNo 煤矿所属的区县编码
     *
     */
    boil.setCountyNo = function (countyNo) {
        boil.setPrefs("COUNTY_NO", ($.isBlank(countyNo) ? "" : countyNo));
    };

    /**
     *
     * 获取偏好中的煤矿所属的区县编码。
     *
     * @return {string} 偏好中的煤矿所属的区县编码
     *
     */
    boil.getCountyNo = function () {
        return ($.isBlank(boil.getPrefs("COUNTY_NO")) ? "" : boil.getPrefs("COUNTY_NO"));
    };

    /**
     *
     * 设置偏好中的煤矿所属的区县名称。
     *
     * @param countyName 煤矿所属的区县名称
     *
     */
    boil.setCountyName = function (countyName) {
        boil.setPrefs("COUNTY_NAME", ($.isBlank(countyName) ? "" : countyName));
    };

    /**
     *
     * 获取偏好中的煤矿所属的区县名称。
     *
     * @return {string} 偏好中的煤矿所属的区县名称
     *
     */
    boil.getCountyName = function () {
        return ($.isBlank(boil.getPrefs("COUNTY_NAME")) ? "" : boil.getPrefs("COUNTY_NAME"));
    };

    /**
     *
     * 设置偏好中的煤矿编码。
     *
     * @param mineNo 煤矿编码
     *
     */
    boil.setMineNo = function (mineNo) {
        boil.setPrefs("MINE_NO", ($.isBlank(mineNo) ? "" : mineNo));
    };

    /**
     *
     * 获取偏好中的煤矿编码。
     *
     * @return {string} 偏好中的煤矿编码
     *
     */
    boil.getMineNo = function () {
        return ($.isBlank(boil.getPrefs("MINE_NO")) ? "" : boil.getPrefs("MINE_NO"));
    };

    /**
     *
     * 设置偏好中的组织机构编码。
     *
     * @param orgNo 组织机构编码
     *
     */
    boil.setOrgNo = function (orgNo) {
        boil.setPrefs("ORG_NO", ($.isBlank(orgNo) ? "" : orgNo));
    };

    /**
     *
     * 获取偏好中的组织机构编码。
     *
     * @return {string} 偏好中的组织机构编码
     *
     */
    boil.getOrgNo = function () {
        return ($.isBlank(boil.getPrefs("ORG_NO")) ? "" : boil.getPrefs("ORG_NO"));
    };

    /**
     *
     * 设置偏好中的煤矿名称。
     *
     * @param mineName 煤矿名称
     *
     */
    boil.setMineName = function (mineName) {
        boil.setPrefs("MINE_NAME", ($.isBlank(mineName) ? "" : mineName));
    };

    /**
     *
     * 获取偏好中的煤矿名称。
     *
     * @return {string} 偏好中的煤矿名称
     *
     */
    boil.getMineName = function () {
        return ($.isBlank(boil.getPrefs("MINE_NAME")) ? "" : boil.getPrefs("MINE_NAME"));
    };

    /**
     *
     * 设置偏好中的组织机构编码。
     *
     * @param zuNo 组织机构编码
     *
     */
    boil.setZuNo = function (zuNo) {
        boil.setPrefs("ZU_NO", ($.isBlank(zuNo) ? "" : zuNo));
    };

    /**
     *
     * 获取偏好中的组织机构编码。
     *
     * @return {string} 偏好中的组织机构编码
     *
     */
    boil.getZuNo = function () {
        return ($.isBlank(boil.getPrefs("ZU_NO")) ? "" : boil.getPrefs("ZU_NO"));
    };

    /**
     *
     * 清空偏好中的登录信息。
     *
     */
    boil.clearLoginInfo = function () {
        boil.removePrefs("USERNAME");
        boil.removePrefs("PASSWD");
        boil.removePrefs("LOGIN_FLAG");
    };

    /**
     *
     * 清空偏好中的煤矿基本信息。
     *
     */
    boil.clearMineInfo = function () {
        boil.removePrefs("MINE_NO");
        boil.removePrefs("MINE_NAME");
        boil.removePrefs("ZU_NO");
    };

    /**
     *
     * 清空偏好中的煤矿所有信息。
     *
     */
    boil.clearAllMineInfo = function () {
        boil.removePrefs("LOGIN_COUNTY_NO");
        boil.removePrefs("LOGIN_COUNTY_NAME");
        boil.removePrefs("COUNTY_NO");
        boil.removePrefs("COUNTY_NAME");
        boil.removePrefs("MINE_NO");
        boil.removePrefs("MINE_NAME");
        boil.removePrefs("ZU_NO");
    };

    /**
     *
     * 将字符串转换为 JSON。
     *
     * @param str 字符串
     * @return {Object} JSON 对象
     *
     */
    boil.strToJson = function (str) {
        try {
            if ($.isNotBlank(str)) {
                return $api.strToJson(str);
            }
        } catch (e) {
        }

        return {};
    };

    /**
     *
     * 将 JSON 转换为字符串。
     *
     * @param json JSON 对象
     * @return {string} 字符串
     *
     */
    boil.jsonToStr = function (json) {
        try {
            if ($.isObject(json) || $.isArray(json)) {
                return $api.jsonToStr(json);
            }
        } catch (e) {
        }

        return "";
    };

    /**
     *
     * 打开窗口。
     *
     * @param settings 配置信息，JSON 对象
     *
     */
    boil.openWin = function (settings) {
        if (!$.isObject(settings) || //
            $.isBlank(settings.name) || //
            $.isBlank(settings.url)) {
            return;
        }

        // 页面参数
        settings.pageParam = ($.isObject(settings.pageParam) ? settings.pageParam : {});
        // 是否显示水平滚动条：true-是；false-否
        settings.hScrollBarEnabled = ($.isBoolean(settings.hScrollBarEnabled) ? settings.hScrollBarEnabled : false);
        // 是否显示垂直滚动条：true-是；false-否
        settings.vScrollBarEnabled = ($.isBoolean(settings.vScrollBarEnabled) ? settings.vScrollBarEnabled : false);

        api.openWin({
            name: settings.name,
            url: settings.url,
            pageParam: settings.pageParam,
            hScrollBarEnabled: settings.hScrollBarEnabled,
            vScrollBarEnabled: settings.vScrollBarEnabled
        });
    };

    /**
     *
     * 关闭窗口。
     *
     * @param winName 窗口名称
     *
     */
    boil.closeWin = function (winName) {
        if ($.isBlank(winName)) {
            api.closeWin();
        } else {
            api.closeWin({
                name: winName
            });
        }
    };

    /**
     *
     * 去掉字符串前后空格。
     *
     * @param str 被操作字符串
     *
     */
    boil.trim = function (str) {
        return $api.trim(str);
    };

    /**
     *
     * 获取页面传递参数。
     *
     * @return {object} 页面参数
     *
     */
    boil.getPageParam = function () {
        return api.pageParam;
    };

    /**
     *
     * 设置屏幕旋转方向。
     *
     * @param orientation 方向
     * <ol>
     *     <li>auto：屏幕根据重力感应在横竖屏间自动切换；</li>
     *     <li>auto_portrait：屏幕根据重力感应在竖屏间自动切换；</li>
     *     <li>auto_landscape：屏幕根据重力感应在横屏间自动切换；</li>
     *     <li>portrait_up：竖屏时，屏幕在home键的上面；</li>
     *     <li>portrait_down：竖屏时，屏幕在home键的下面，部分手机不支持；</li>
     *     <li>landscape_left：横屏时，屏幕在home键的左边；</li>
     *     <li>landscape_right：横屏时，屏幕在home键的右边。</li>
     * </ol>
     *
     */
    boil.setScreenOrientation = function (orientation) {
        if ($.isNotBlank(orientation) && !$.isNumber(orientation)) {
            api.setScreenOrientation({
                orientation: orientation
            });
        }
    };

    /**
     *
     * 获取窗口的宽度。
     *
     */
    boil.getWinWidth = function () {
        return api.winWidth;
    };

    /**
     *
     * 获取窗口的高度。
     *
     */
    boil.getWinHeight = function () {
        return api.winHeight;
    };

    /**
     *
     * 发送 Ajax 请求，支持跨域。
     *
     * @param settings 配置信息，JSON 对象
     *
     */
    boil.ajax = function (settings) {
        if (!$.isObject(settings)) {
            return;
        }

        // 请求  Url
        settings.url = ($.isBlank(settings.url) ? "" : settings.url);
        // 是否对 url 进行编码：true-是；false-否
        settings.encode = ($.isBoolean(settings.encode) ? settings.encode : true);
        // 请求标识，可以传递此字段给 cancelAjax 方法来取消请求
        settings.tag = ($.isBlank(settings.tag) ? "" : settings.tag);
        // 请求方式
        settings.method = ($.isBlank(settings.method) ? "get" : settings.method.toLowerCase());
        // 是否缓存，若缓存，下次没网络时请求则会使用缓存：true-是；false-否
        settings.cache = ($.isBoolean(settings.cache) ? settings.cache : false);
        // 超时时间，单位秒
        settings.timeout = ($.isNumber(settings.timeout) ? settings.timeout : 30);
        // 超时时间，单位秒
        settings.dataType = ($.isBlank(settings.dataType) ? "json" : settings.dataType.toLowerCase());
        // 当响应头里面没有返回字符集编码时，使用此编码来解析数据
        settings.charset = ($.isBlank(settings.charset) ? "utf-8" : settings.charset.toLowerCase());
        // 请求头，JSON 对象
        settings.headers = ($.isObject(settings.headers) ? settings.headers : {});
        // 是否实时返回上传文件进度：true-是；false-否
        settings.report = ($.isBoolean(settings.report) ? settings.report : false);
        // 是否需要返回所有 response 信息，为 true 时，返回的头信息获取方法(ret.headers)，消息体信息获取方法(ret.body)，状态码获取方法(ret.statusCode)：true-是；false-否
        settings.returnAll = ($.isBoolean(settings.returnAll) ? settings.returnAll : false);
        // POST 数据，method 为 get 时不传。以下字段除了 values 和 files 可以同时使用，其它参数都不能同时使用
        settings.data = ($.isObject(settings.data) ? settings.data : {});
        // https 安全证书设置
        settings.certificate = ($.isObject(settings.certificate) ? settings.certificate : {});
        // 是否显示等待框
        settings.loading = ($.isBoolean(settings.loading) ? settings.loading : false);
        // 等待消息
        settings.msg = ($.isBlank(settings.msg) ? "数据加载中……" : msg);

        ajaxCount++;

        if (settings.loading) {
            ajaxLodingCount++;

            if (ajaxLodingCount === 1) {
                boil.showProgress(settings.msg);
            }
        }

        // 请求开始之前执行
        if ($.isFunction(settings.beforeFn)) {
            settings.beforeFn();
        }

        api.ajax({
            url: settings.url,
            encode: settings.encode,
            tag: settings.tag,
            method: settings.method,
            cache: settings.cache,
            timeout: settings.timeout,
            dataType: settings.dataType,
            charset: settings.charset,
            headers: settings.headers,
            report: settings.report,
            returnAll: settings.returnAll,
            data: settings.data,
            certificate: settings.certificate
        }, function (ret, err) {
            if (ajaxCount > 0) {
                ajaxCount--;
            }

            if (settings.loading) {
                if (ajaxLodingCount > 0) {
                    ajaxLodingCount--;
                }

                if (ajaxLodingCount === 0) {
                    boil.hideProgress();
                }
            }

            // 请求完成执行
            if ($.isFunction(settings.completeFn)) {
                settings.completeFn();
            }

            if (settings.dataType === "json") {
                // 请求成功
                if (ret) {
                    if ($.isFunction(settings.successFn)) {
                        settings.successFn(ret);
                    }

                    // 请求失败
                } else {
                    boil.toast(err.msg);

                    if ($.isFunction(settings.errorFn)) {
                        settings.errorFn(err);
                    }
                }
            } else {
                // 请求成功
                if ($.isNotBlank(ret)) {
                    if ($.isFunction(settings.successFn)) {
                        settings.successFn(ret);
                    }

                    // 请求失败
                } else {
                    boil.toast("暂无数据");

                    if ($.isFunction(settings.errorFn)) {
                        settings.errorFn(err);
                    }
                }
            }
        });
    };

    /**
     *
     * 字符串换行处理。
     *
     * @param str 字符串
     * @param splitCount 每隔多个字符
     * @return {string} 换行后的字符串
     *
     */
    boil.newlineStr = function (str, splitCount) {
        // 换行后的字符串
        var newlineStr = "";

        if ($.isBlank(str) || !$.isNumber(splitCount)) {
            return "";
        }

        splitCount = Number(splitCount);

        if ((splitCount <= 0) || (str.length <= splitCount)) {
            return str;
        } else {
            var split = (str.length / splitCount);

            for (var i = 0; i < split; i++) {
                /*
                 if (i < (split - 1)) {
                 newlineStr += (str.substring((i * splitCount), ((i + 1) * splitCount)) + "\n");
                 } else {
                 newlineStr += str.substring((i * splitCount), ((i + 1) * splitCount));
                 }
                 */

                if (i === 0) {
                    newlineStr += str.substring((i * splitCount), ((i + 1) * splitCount));
                } else {
                    newlineStr += ("\n" + str.substring((i * splitCount), ((i + 1) * splitCount)));
                }
            }

            // 非整除
            if ((str.length % splitCount) !== 0) {
                newlineStr += ("\n" + str.substring((split * splitCount)));
            }
        }

        return newlineStr;
    };

    /**
     *
     * 中文字符串换行处理。
     *
     * @param chineseStr 中文字符串
     * @param splitCount 每隔多个中文换行
     * @return {string} 换行后的中文字符串，如果包含非中文字符串，将返回空串
     *
     */
    boil.newlineChineseStr = function (chineseStr, splitCount) {
        // 中文的正则表达式
        var chineseRE = /^[\u4e00-\u9fa5]+$/i;

        if ($.isBlank(chineseStr) || !chineseRE.test(chineseStr)) {
            return "";
        }

        return boil.newlineStr(chineseStr, splitCount);
    };

    /**
     *
     * 数组求和。
     *
     * @param arr 数字数组
     * @return {number} 和
     *
     */
    boil.sumArray = function (arr) {
        var sum = 0;

        if ($.isArray(arr)) {
            $.each(arr, function (i, e) {
                if ($.isNumber(e)) {
                    sum += Number(e);
                }
            });
        }

        return sum;
    };

    /**
     *
     * 给对象数组中对象的某个字段求和。
     *
     * @param objArr 对象数组
     * @param objField 对象字段
     * @return {number} 和
     *
     */
    boil.sumObjArray = function (objArr, objField) {
        var sum = 0;

        if ($.isArray(objArr) && $.isNotBlank(objField) && !$.isNumber(objField)) {
            $.each(objArr, function (i, e) {
                if ($.isObject(e)) {
                    var value = e[objField];

                    if ($.isNumber(value)) {
                        sum += Number(value);
                    }
                }
            });
        }

        return sum;
    };

    /**
     *
     * 判断 str 是否以 startsStr 开始。
     *
     * @param str 字符串
     * @param startsStr 开始的字符串
     * @return {boolean}
     * <ol>
     *    <li>true-是；</li>
     *    <li>false-否。</li>
     * </ol>
     *
     */
    boil.startsWithStr = function (str, startsStr) {
        if ($.isBlank(str) || $.isBlank(startsStr)) {
            return false;
        }

        if (str.indexOf(startsStr) === 0) {
            return true
        } else {
            return false;
        }
    };

    /**
     *
     * 判断 str 是否以 endsStr 结束。
     *
     * @param str 字符串
     * @param endsStr 结束的字符串
     * @return {boolean}
     * <ol>
     *    <li>true-是；</li>
     *    <li>false-否。</li>
     * </ol>
     *
     */
    boil.endsWithStr = function (str, endsStr) {
        if ($.isBlank(str) || $.isBlank(endsStr)) {
            return false;
        }

        if ((str.lastIndexOf(endsStr) + endsStr.length) === str.length) {
            return true
        } else {
            return false;
        }
    };

    /**
     *
     * 给基本类型数组排序。
     *
     * @param arr 数组
     * @param sortBy 排序方式：
     * <ol>
     *    <li>asc-升序；</li>
     *    <li>desc-降序。</li>
     * </ol>
     *
     * @return {*|Array.<T>} 排序后的数组
     *
     */
    boil.sortArray = function (arr, sortBy) {
        if (!$.isArray(arr)) {
            return new Array();
        }

        if ($.isBlank(sortBy)) {
            return arr;
        }

        sortBy = String(sortBy).toLowerCase();

        if (("asc" !== sortBy) && ("desc" !== sortBy)) {
            return arr;
        }

        // 比较器
        var compare = function (v1, v2) {
            // v1 和 v2 其中一个为空，禁止排序
            if ($.isBlank(v1) || $.isBlank(v2)) {
                return 0;
            }

            // 升序
            if (sortBy === "asc") {
                if (v1 > v2) {
                    return 1;
                } else if (v1 < v2) {
                    return -1;
                } else {
                    return 0;
                }

                // 降序
            } else if (sortBy === "desc") {
                if (v1 > v2) {
                    return -1;
                } else if (v1 < v2) {
                    return 1;
                } else {
                    return 0;
                }

                // 什么玩意？
            } else {
                return 0;
            }
        }

        return arr.sort(compare);
    };

    /**
     *
     * 给对象数组排序。
     *
     * @param objArr 对象数组
     * @param sortField 排序字段
     * @param sortBy 排序方式：
     * <ol>
     *    <li>asc-升序；</li>
     *    <li>desc-降序。</li>
     * </ol>
     *
     * @return {*|Array.<T>} 排序后的数组
     *
     */
    boil.sortObjArray = function (objArr, sortField, sortBy) {
        if (!$.isArray(objArr)) {
            return new Array();
        }

        if ($.isBlank(sortField) || $.isNumber(sortField) || $.isBlank(sortBy)) {
            return objArr;
        }

        sortField = String(sortField);
        sortBy = String(sortBy).toLowerCase();

        if (("asc" !== sortBy) && ("desc" !== sortBy)) {
            return objArr;
        }

        // 比较器
        var compare = function (o1, o2) {
            // o1 和 o2 其中一个不为对象，禁止排序
            if (!$.isObject(o1) || !$.isObject(o2)) {
                return 0;
            }

            var v1 = ($.isNumber(o1[sortField]) ? Number(o1[sortField]) : 0);
            var v2 = ($.isNumber(o2[sortField]) ? Number(o2[sortField]) : 0);

            // 升序
            if (sortBy === "asc") {
                if (v1 > v2) {
                    return 1;
                } else if (v1 < v2) {
                    return -1;
                } else {
                    return 0;
                }

                // 降序
            } else if (sortBy === "desc") {
                if (v1 > v2) {
                    return -1;
                } else if (v1 < v2) {
                    return 1;
                } else {
                    return 0;
                }

                // 什么玩意？
            } else {
                return 0;
            }
        }

        return objArr.sort(compare);
    };

    /**
     *
     * 获取安全的字符串。
     *
     * @param str 字符串
     * @return {string} 安全的字符串
     *
     */
    boil.getString = function (str) {
        return ($.isBlank(str) ? "" : String(str));
    };

    /**
     *
     * 获取安全的数字。
     *
     * @param num 数字
     * @return {number} 安全的数字
     *
     */
    boil.getNumber = function (num) {
        return ($.isNumber(num) ? Number(num) : 0);
    };

    /**
     *
     * 获取安全的布尔。
     *
     * @param bl 布尔
     * @return {boolean} 安全的布尔
     *
     */
    boil.getBoolean = function (bl) {
        return ($.isBoolean(bl) ? Boolean(bl) : false);
    };

    /**
     *
     * 设置标题。
     *
     * @param title 标题
     *
     */
    boil.setTitle = function (title) {
        // 页面头部的 jQuery 对象
        var $page_head = $(".page-head");
        // 标题的 jQuery 对象
        var $title = $page_head.find(".title");
        // 左侧 icon 的 jQuery 对象
        var $icon_span_left = $page_head.find(".icon-span-left");
        // 右侧 icon 的 jQuery 对象
        var $icon_span_right = $page_head.find(".icon-span-right");
        // 页面头部的宽度
        var page_head_width = 0;
        // 左侧 icon 的宽度
        var icon_span_left_width = 0;
        // 右侧 icon 的宽度
        var icon_span_right_width = 0;
        // 标题的宽度
        var title_width = 0;

        if ($.is_jQueryObj($page_head)) {
            page_head_width = boil.getNumber($page_head.width());
        }

        if ($.is_jQueryObj($icon_span_left)) {
            icon_span_left_width = boil.getNumber($icon_span_left.width());
        }

        if ($.is_jQueryObj($icon_span_right)) {
            icon_span_right_width = boil.getNumber($icon_span_right.width());
        }

        title_width = (page_head_width - icon_span_left_width - icon_span_right_width);

        if (title_width < 0) {
            title_width = 0;
        }

        if ($.is_jQueryObj($title)) {
            $title.width(title_width).html(boil.getString(title));
        }
    };

    /**
     *
     * 获取全屏暂无数据的 HTML 代码。
     *
     */
    boil.getFullScreenNoDataHtml = function () {
        // 页面头部的 jQuery 对象
        var $page_head = $(".page-head");
        // 页面头部的宽度
        var page_head_height = 0;
        // 暂无数据的高度
        var noDataHeight = 0;

        if ($.is_jQueryObj($page_head)) {
            page_head_height = boil.getNumber($page_head.height());
        }

        noDataHeight = (boil.getWinHeight() - page_head_height);

        return "<div style='color: grey; height: {0}px; font-size: 18px; text-align: center; line-height: {0}px; background-color: white;'>暂无数据</div>".format(noDataHeight);
    };

    /**
     *
     * 根据 fieldKey 在 field 上从 objArr 中查找对象。
     *
     * @param objArr 对象数组
     * @param field 字段
     * @param fieldKey 字段键，即查找对象的字段值，在 objArr 中需要保证它是唯一的才有意义
     * @return {Object} key 对应的对象
     *
     */
    boil.getObjFromObjArr = function (objArr, field, fieldKey) {
        var obj = null;

        if ($.isArray(objArr) && $.isNotBlank(field) && !$.isNumber(field) && $.isNotBlank(fieldKey)) {
            $.each(objArr, function (i, e) {
                if ($.isObject(e)) {
                    if (e[field] == fieldKey) {
                        obj = e;

                        // 终止循环
                        return false;
                    }
                }
            });
        }

        return obj;
    };

    window.$boil = boil;
})(window);


$(function () {
    var $window = $(window);
    var $panelHeight = $(".panel-height");
    // 返回按钮
    var $back_btn = $("#back_btn");

    if ($.is_jQueryObj($panelHeight)) {
        $panelHeight.css("height", $window.height());
    }

    // 监听窗口大小改变
    $window.resize(function () {
        if ($.is_jQueryObj($panelHeight)) {
            $panelHeight.css("height", $window.height());
        }
    });

    // 点击返回按钮
    if ($.is_jQueryObj($back_btn)) {
        $back_btn.click(function () {
            $boil.closeWin(api.winName);
        });
    }
});